home *** CD-ROM | disk | FTP | other *** search
/ Java Developer's Companion / Java Developer's Companion.iso / Javacup / INGZP26A.TAR / internet / INGZP26A / MapPanel.java < prev    next >
Encoding:
Java Source  |  1996-05-21  |  11.6 KB  |  435 lines

  1. /* $Id: MapPanel.java,v 1.7 1996/03/31 11:43:02 djun Exp djun $
  2.  
  3.    File: MapPanel.java
  4.  
  5.    Author: Djun M. Kim
  6.    Copyright (c) 1996 Djun M. Kim.  All rights reserved.
  7.  
  8. */
  9.  
  10. import java.applet.Applet;
  11. import java.awt.image.*;
  12. import java.awt.*;
  13. import java.util.*;
  14. import Location;
  15. import MapError;
  16.  
  17. class MapPanel extends gridPanel implements Runnable {
  18.  
  19.     MapInfo parent;
  20.  
  21.     // The tread running this panel
  22.     Thread runner;    
  23.  
  24.     MapCanvas canvas;
  25.     ScaleCtrls scale_ctrls;
  26.  
  27.     MapPanel(MapInfo target) {
  28.     super(target);
  29.     this.parent = target;
  30.      canvas = new MapCanvas(parent);
  31.      scale_ctrls = new ScaleCtrls(parent);
  32.  
  33.     //       Panel     gridx    gridy    Weightx Weighty GridW   GridH
  34.     make_canvas(canvas,      1,    1,    1.0,    1.0,    REMN,    1);
  35.     make_panel(scale_ctrls,     1,    2,    1.0,    0.0,    REMN,    1);
  36.     };
  37.  
  38.  
  39.     // Methods to handle the thread
  40.     public void start () {
  41.     if (runner == null) {
  42.         runner = new Thread(this);
  43.         runner.start();
  44.     }
  45.     }
  46.  
  47.     public void stop () {
  48.     if (runner != null) {
  49.         runner.stop();
  50.         runner = null;
  51.     }
  52.     }
  53.  
  54.     public void run() {
  55.     canvas.repaint();
  56.     }
  57. }
  58.  
  59.  
  60. class MapCanvas extends Canvas {
  61.  
  62.     MapInfo parent;
  63.  
  64.     MapError error_handler = new MapError();
  65.    
  66.     // Instance variables for double buffering
  67.     private Image hiddenimagebuffer;
  68.     private Graphics hiddengraphics;
  69.  
  70.     private Font trb18 = new Font("TimesRoman", Font.BOLD, 18);
  71.  
  72.     private Location loc;        // location of pointer on the map
  73.     private flashingLocation selected_location;    // current selected location
  74.  
  75.     final int xsize = parent.map.XSIZE;
  76.     final int ysize = parent.map.YSIZE;
  77.  
  78.     private int map_xpos = 0;
  79.     private int map_ypos = 0;
  80.     private int map_xbase = 0;
  81.     private int map_ybase = 0;
  82.    
  83.     int screen_xpos = 0;
  84.     int screen_ypos = 0;
  85.  
  86.     private int save_x0 = 0;        // used to compute translations when
  87.     private int save_y0 = 0;        // repositioning the map
  88.     private int save_x1 = 0;    
  89.     private int save_y1 = 0;    
  90.  
  91.     private int delta_x = 0;
  92.     private int delta_y = 0;
  93.  
  94.     MapCanvas(MapInfo target) {
  95.     super();
  96.     this.parent = target;
  97.     this.resize(xsize, ysize);
  98.     }
  99.  
  100.     // Utility methods
  101.     private final int scale(int param) {
  102.     int mapscale = parent.mapview.scale_ctrls.getScale();
  103.     return(java.lang.Math.round(param * mapscale / 100));
  104.     }
  105.  
  106.     private final int unscale(int param) {
  107.     int mapscale = parent.mapview.scale_ctrls.getScale();
  108.     try {
  109.         return(java.lang.Math.round(param * 100 / mapscale));
  110.     }
  111.     catch (java.lang.ArithmeticException e) {
  112.         error_handler.display("Arithmetic exception:"+e.getMessage());
  113.         return(0);
  114.     };
  115.     }
  116.     private final Region scaleRegion(Region reg) {
  117.     Polygon poly = reg.perim;
  118.     Polygon scaledPoly = 
  119.         new Polygon(poly.xpoints, poly.ypoints, poly.npoints);
  120.     Region scaledRegion = new Region();
  121.     for (int i = 0; i < poly.npoints; i++) {
  122.         scaledPoly.xpoints[i] = scale(poly.xpoints[i]);
  123.         scaledPoly.ypoints[i] = scale(poly.ypoints[i]);
  124.     }
  125.     scaledRegion.perim = scaledPoly;
  126.     return(scaledRegion);
  127.     }
  128.  
  129.     // Translate the graphics back to top left corner 
  130.     public void topAlign() {
  131.     synchronized (hiddengraphics) {
  132.         hiddengraphics.translate(map_xbase, map_ybase);
  133.     }
  134.     map_xbase = 0;
  135.     map_ybase = 0;
  136.     }
  137.  
  138.     // Mouse methods
  139.     public boolean mouseDown(Event evt, int x, int y){    
  140.     int Function = parent.ctrlview.getPanelFunction();    
  141.     if (Function == parent.ctrlview.getLocationInfo) {
  142.         parent.ctrlview.display_layout.show((Container)parent.ctrlview.display,
  143.          "info_display");
  144.         parent.ctrlview.info_display.showLocationInfo(map_xpos, map_ypos);
  145.         setSelectedLocation((Location)loc);        // record location
  146.         return true;
  147.     } else if (Function == parent.ctrlview.getRouteInfo) {
  148.         parent.ctrlview.display_layout.show((Container)parent.ctrlview.display,
  149.          "route_display");
  150.         //parent.ctrlview.info_display.showRouteInfo(map_xpos, map_ypos);
  151.         setSelectedLocation((Location)loc);        // record location
  152.         return true;
  153.     } else if (Function == parent.ctrlview.getDetailInfo) {
  154.         parent.ctrlview.display_layout.show((Container)parent.ctrlview.display,
  155.          "detail_display");
  156.         // The following line may be used to generate the polygons for regions
  157.         // defining locations, in Map.java.
  158.         System.out.println("\tp.addPoint(" + map_xpos + ", " + map_ypos + ");");
  159.         return true;
  160.     } else { // default
  161.         showLocationCoords(map_xpos, map_ypos);
  162.         return true;
  163.     }
  164.     }
  165.  
  166.     public boolean mouseMove(Event evt, int x, int y){
  167.     if (x < 0) 
  168.             {screen_xpos = 0;}
  169.     else if (x > xsize)
  170.         {screen_xpos = xsize;}
  171.     else 
  172.         {screen_xpos = x;}
  173.     if (y < 0) 
  174.             {screen_ypos = 0;}
  175.     else if (y > ysize)
  176.         {screen_ypos = ysize;}
  177.     else 
  178.         {screen_ypos = y;}
  179.     map_xpos = unscale(screen_xpos + map_xbase);
  180.     map_ypos = unscale(screen_ypos + map_ybase);
  181.     parent.setInfo("x:"+map_xpos+", y:"+map_ypos);
  182.     loc = parent.map.getLocation(map_xpos, map_ypos);
  183.     repaint(); 
  184.     return true;
  185.     }
  186.  
  187.  
  188.     public boolean mouseDrag(Event evt, int x, int y){
  189.     if ((x > 0) && (x < xsize) && (y > 0) && (y < ysize)) {
  190.         save_x0 = save_x1;
  191.         save_x1 = x;
  192.         save_y0 = save_y1;
  193.         save_y1 = y;
  194.         delta_x = save_x1 - save_x0;
  195.         delta_y = save_y1 - save_y0;
  196.         // prevent that initial "jump" by making sure deltas are small
  197.         if ((java.lang.Math.abs(delta_x) < 30) && 
  198.         (java.lang.Math.abs(delta_y) < 30)) {    
  199.         if ((map_xbase - delta_x >=0) &&
  200.             (map_ybase - delta_y >=0) &&
  201.             (map_xbase - delta_x <= scale(xsize)-xsize) &&
  202.             (map_ybase - delta_y <= scale(ysize)-ysize))
  203.  
  204.         {
  205.             synchronized (hiddengraphics) {
  206.             hiddengraphics.translate(delta_x, delta_y);
  207.             }
  208.             map_xbase = map_xbase - delta_x;
  209.             map_ybase = map_ybase - delta_y;
  210.             repaint();
  211.         } 
  212.         }
  213.         if (x < 0) 
  214.         {screen_xpos = 0;}
  215.         else if (x > xsize)
  216.         {screen_xpos = xsize;}
  217.         else 
  218.         {screen_xpos = x;}
  219.         if (y < 0) 
  220.             {screen_ypos = 0;}
  221.         else if (y > ysize)
  222.         {screen_ypos = ysize;}
  223.         else 
  224.         {screen_ypos = y;}
  225.         map_xpos = unscale(screen_xpos + map_xbase);
  226.         map_ypos = unscale(screen_ypos + map_ybase);
  227.         loc = parent.map.getLocation(map_xpos, map_ypos);
  228.         return true;
  229.     }
  230.     return false;
  231.     }
  232.  
  233.     /*-----------------
  234.      GIS Methods
  235.      -----------------*/
  236.  
  237.     // Show x-y coordinates of Location pointed to.
  238.     public void showLocationCoords(int x, int y) {
  239.      parent.ctrlview.showCoords(x, y);
  240.     }
  241.  
  242.  
  243.     // Return current Location 
  244.     public Location getLocation() {
  245.      return(loc);
  246.     }
  247.  
  248.     // Return current selected location 
  249.     public flashingLocation getSelectedLocation() {
  250.      return(selected_location);
  251.     }
  252.  
  253.     // Set the current selected location 
  254.     public void setSelectedLocation(Location loc) {
  255.     if (loc != null) {
  256.         selected_location = new flashingLocation(parent.map, loc, 500);
  257.         selected_location.start();
  258.     } else
  259.         selected_location = null;
  260.     }
  261.  
  262.     // Graphics methods
  263.  
  264.     public void paint(Graphics g) {
  265.     if (hiddengraphics == null) {
  266.         hiddenimagebuffer = 
  267.         createImage(this.size().width, this.size().height);
  268.         hiddengraphics = hiddenimagebuffer.getGraphics();
  269.     }
  270.     int width = xsize;
  271.     int height = ysize;
  272.     // since we translate hiddengraphics in mouseDrag, we must
  273.     // translate "back" to get true screen position for the cursor
  274.     // crosshairs
  275.     int true_x = screen_xpos + map_xbase;
  276.     int true_y = screen_ypos + map_ybase;
  277.  
  278.     g.clipRect(0, 0, width+1, height+1);
  279.     setBackground(Color.lightGray);
  280.     synchronized (hiddengraphics) {
  281.         hiddengraphics.clearRect(0,0,width,height);
  282.         hiddengraphics.drawImage(parent.map.mapimage, 
  283.         0, 0, scale(width), scale(height), this);
  284.     }
  285.     if (getSelectedLocation() != null) {
  286.         flashingLocation loc = getSelectedLocation();
  287.         if (loc.is_on()) {
  288.         highlightLocation(loc, Color.blue);
  289.         } else {
  290.         highlightLocation(loc, Color.red);
  291.         }
  292.     }
  293.     int Function =     parent.ctrlview.getPanelFunction();
  294.     if (Function == parent.ctrlview.getLocationInfo) {
  295.         highlightLocation(loc);
  296.     } else if (Function == parent.ctrlview.getRouteInfo) {
  297.         highlightCarrier(loc);
  298.     }
  299.     synchronized (hiddengraphics) {
  300.         if (loc != null) {    
  301.         hiddengraphics.setColor(Color.white);
  302.         hiddengraphics.setFont(trb18);
  303.         hiddengraphics.drawString(loc.getName(), true_x+5, true_y-5);
  304.         hiddengraphics.drawString(loc.getName(), true_x+3, true_y-4);
  305.         hiddengraphics.drawString(loc.getName(), true_x+4, true_y-3);
  306.         hiddengraphics.setColor(Color.black);
  307.         hiddengraphics.drawString(loc.getName(), true_x+4, true_y-4);
  308.         }
  309.         hiddengraphics.setColor(Color.blue);
  310.         // vertical crosshair
  311.         hiddengraphics.drawLine(true_x, 0, true_x, scale(ysize));
  312.         // horizontal crosshair
  313.         hiddengraphics.drawLine(0, true_y, scale(xsize), true_y);
  314.         // frame around image
  315.         hiddengraphics.setColor(Color.black);        
  316.         hiddengraphics.drawRect(map_xbase, map_ybase, width, height);
  317.         // now refresh the actual screen 
  318.     }
  319.     g.drawImage(hiddenimagebuffer, 0, 0, this);
  320.     }
  321.  
  322.     public void repaint(Graphics g){
  323.     paint(g);
  324.     }
  325.  
  326.     public void update(Graphics g){
  327.     paint(g);
  328.     }
  329.  
  330.     // highlight the location at point loc in the hidden graphics
  331.     public void highlightLocation(Location loc) {
  332.     Color col;
  333.     if (loc != null) {
  334.         if (loc instanceof Road)
  335.         col = Color.black;
  336.         else if (loc instanceof Building)
  337.         col = Color.red;
  338.         else if (loc instanceof Park)
  339.         col = Color.green;
  340.         else
  341.         col = Color.gray;
  342.         if (loc.isDisplayable()) {
  343.         synchronized (hiddengraphics) {
  344.             hiddengraphics.setColor(col); 
  345.             hiddengraphics.fillPolygon(
  346.             scaleRegion(loc.getRegion()).perim);
  347.         }
  348.         }
  349.     }
  350.     }
  351.  
  352.     // highlight the location at point loc in the hidden graphics
  353.     // with a particular color
  354.     public void highlightLocation(Location loc, Color col) {
  355.     if (loc != null) {
  356.         if (loc.isDisplayable()) {
  357.         synchronized (hiddengraphics) {
  358.             hiddengraphics.setColor(col); 
  359.             hiddengraphics.fillPolygon(
  360.             scaleRegion(loc.getRegion()).perim);
  361.         }
  362.         }
  363.     }
  364.     }
  365.  
  366.     // highlight the carriers incident at location loc
  367.     public void highlightCarrier(Location loc) {
  368.     if (loc != null) {
  369.         synchronized (hiddengraphics) {
  370.         hiddengraphics.setColor(Color.blue); 
  371.         }
  372.         for (Enumeration e = loc.exits.elements(); e.hasMoreElements();) {
  373.         Carrier c = (Carrier)e.nextElement();
  374.         Region r = c.getRegion();
  375.         synchronized (hiddengraphics) {
  376.             hiddengraphics.fillPolygon(scaleRegion(r).perim);
  377.         }
  378.         }
  379.         for (Enumeration e = loc.entrances.elements(); e.hasMoreElements();) {
  380.         Carrier c = (Carrier)e.nextElement();
  381.         Region r = c.getRegion();
  382.         synchronized (hiddengraphics) {
  383.             hiddengraphics.fillPolygon(scaleRegion(r).perim);
  384.         }
  385.         }
  386.     }
  387.     }
  388. }
  389.  
  390. class ScaleCtrls extends Panel {
  391.     private MapInfo parent;
  392.     private int scalefactor = 100;            // scale factor in percent
  393.     private int scale_incr = 20;            // increase factor by this amnt
  394.     private Label  scale_label = new Label("Map Scale: 100%");
  395.     private Button zoom = new Button("Zoom");
  396.     private Button unzoom = new Button("Unzoom");
  397.  
  398.  
  399.     ScaleCtrls(MapInfo target) {
  400.         super();
  401.     this.parent = target;
  402.     setLayout(new GridLayout(1, 3));
  403.     add(scale_label);
  404.     add(zoom);
  405.     add(unzoom);
  406.     }
  407.  
  408.     public int getScale() {
  409.     return scalefactor;
  410.     }
  411.  
  412.     public boolean handleEvent(Event evt) {
  413.     if (evt.target instanceof Button) {
  414.         Button b = (Button)evt.target;
  415.         if (b == zoom) {
  416.         if (scalefactor + scale_incr <= parent.map.MaxScale) {
  417.             scalefactor += scale_incr;
  418.         }
  419.         }        
  420.         if (b == unzoom) {
  421.         if (scalefactor - scale_incr >= parent.map.MinScale) {
  422.             scalefactor -= scale_incr;
  423.             parent.mapview.canvas.topAlign();
  424.         }
  425.         }     
  426.         scale_label.setText("Map Scale: "+scalefactor+"%");   
  427.         parent.mapview.canvas.repaint();
  428.         return true;
  429.     }
  430.     else {
  431.         return false;
  432.     }
  433.     }
  434. }
  435.